//package com.lyt.springboot.aspect;
//
//
////import com.google.gson.Gson;
//import com.lyt.springboot.annotion.RequestLimit;
//import com.lyt.springboot.annotion.WebLog;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.*;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Profile;
//import org.springframework.core.annotation.AnnotationUtils;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Method;
//import java.util.concurrent.TimeUnit;
//
///**
// * 定义一个切面
// *
// * @author lupeng11@meituan.com
// * @date 2020/5/7 15:24
// */
//@Aspect
//@Component
//public class RequestLmitAspect {
//    private final static Logger logger = LoggerFactory.getLogger(RequestLmitAspect.class);
//    @Autowired
//    private RedisTemplate<String, Object> redisTemplate;
//    /**
//     * 换行符
//     */
//    private static final String LINE_SEPARATOR = System.lineSeparator();
//
//    /**
//     * 以自定义的为切点，即使用的地方
//     **/
//    @Pointcut("@annotation(com.lyt.springboot.annotion.RequestLimit)")
//    public void requestLimit() {
//    }
//
//    /**
//     * 环绕
//     * @param proceedingJoinPoint
//     * @return
//     * @throws Throwable
//     */
////    @Around("requestLimit()")
////    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
////        long startTime = System.currentTimeMillis();
////        Object result = proceedingJoinPoint.proceed();
////        // 打印出参
////        logger.info("Response Args  : {}", new Gson().toJson(result));
////        // 执行耗时
////        logger.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
////        return result;
////    }
//
//    /**
//     * 在切点之前织入
//     *
//     * @param joinPoint
//     * @throws Throwable
//     */
////    @Before("requestLimit()")
//    @Around("requestLimit()")
////    public void   doBefore(JoinPoint joinPoint) throws Throwable {
//    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//
//
//        // 开始打印请求日志
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//
////        String methodDescription = getAspectLogDescription(joinPoint);
//
//        // 打印请求相关参数
//        logger.info("========================================== Start ==========================================");
//        // 打印请求 url
//        logger.info("URL            : {}", request.getRequestURL().toString());
//        // 打印描述信息
////        logger.info("Description    : {}", methodDescription);
//        // 打印 Http method
//        logger.info("HTTP Method    : {}", request.getMethod());
//        // 打印调用 controller 的全路径以及执行方法
//        logger.info("Class Method   : {}.{}", proceedingJoinPoint.getSignature().getDeclaringTypeName(), proceedingJoinPoint.getSignature().getName());
//        // 打印请求的 IP
//        logger.info("IP             : {}", request.getRemoteAddr());
//        // 打印请求入参
////        logger.info("Request Args   : {}", new Gson().toJson(proceedingJoinPoint.getArgs()));
//
//        System.out.println("切面限流开始");
//        //利用切面来限流
//        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
//        Method method = signature.getMethod();
//        RequestLimit annotation = AnnotationUtils.findAnnotation(method, RequestLimit.class);
//        int accessMaxTimes = annotation.maxCount();
//        long timeOut = annotation.second();
//        String remoteAddr = request.getRemoteAddr();
//        String servletPath = request.getServletPath();
//        System.out.println("method是" + method);
//        System.out.println("annotation是" + annotation);
//        System.out.println("remoteAddr是" + remoteAddr);
//        System.out.println("servletPath是" + servletPath);
//        System.out.println("accessMaxTimes是" + accessMaxTimes);
//        System.out.println("timeOut是" + timeOut);
//
//        String key = request.getRemoteAddr()+request.getServletPath();
//        Integer value= (Integer)redisTemplate.opsForValue().get(key);
//        if (value == null || value == -1) {
//            redisTemplate.opsForValue().set(key,1,timeOut, TimeUnit.SECONDS);
//            return proceedingJoinPoint.proceed();
//        }
//
//        if(value <accessMaxTimes) {
//            redisTemplate.opsForValue().increment(key);
//            return proceedingJoinPoint.proceed();
//        }
//        throw new RuntimeException("操作频繁");
//}
//
//    /**
//     * 在切点之后织入
//     * @throws Throwable
//     */
//    @After("requestLimit()")
//    public void doAfter() throws Throwable {
//        // 接口结束后换行，方便分割查看
//        logger.info("=========================================== End ===========================================" + LINE_SEPARATOR);
//    }
//
//
//
//    /**
//     * 获取切面注解的描述
//     *
//     * @param joinPoint 切点
//     * @return 描述信息
//     * @throws Exception
//     */
//    public String getAspectLogDescription(JoinPoint joinPoint) throws Exception {
//        String targetName = joinPoint.getTarget().getClass().getName();
//        String methodName = joinPoint.getSignature().getName();
//        Object[] arguments = joinPoint.getArgs();
//        Class targetClass = Class.forName(targetName);
//        Method[] methods = targetClass.getMethods();
//        StringBuilder description = new StringBuilder("");
//        for (Method method : methods) {
//            if (method.getName().equals(methodName)) {
//                Class[] clazzs = method.getParameterTypes();
//                if (clazzs.length == arguments.length) {
//                    description.append(method.getAnnotation(WebLog.class).description());
//                    break;
//                }
//            }
//        }
//        return description.toString();
//    }
//
//
//}
